package zaplog

import (
	"HeadLineNews/settings"
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"log"
	"os"
)

const timeKey = "time"

var logger *zap.Logger
var showCallerLogger *zap.Logger // 显示向上一级的调用的函数
var sugarLogger *zap.SugaredLogger

// getWriteSyncer 日志文件输出句柄
func getWriteSyncer() zapcore.WriteSyncer {
	loggerWriter := &lumberjack.Logger{
		Filename:   settings.Settings.ZapLogConfig.FileName,        // 日志路径
		MaxSize:    int(settings.Settings.ZapLogConfig.MaxSize),    // 最大备份体积： Mb
		MaxAge:     int(settings.Settings.ZapLogConfig.MaxAge),     // 最大备份时间
		MaxBackups: int(settings.Settings.ZapLogConfig.MaxBackups), // 最大备份数量
		LocalTime:  settings.Settings.ZapLogConfig.LocalTime,       // 备份文件名使用本地时间
		Compress:   settings.Settings.ZapLogConfig.Compress,        // 是否压缩
	}
	return zapcore.AddSync(loggerWriter)
}

// getConfigEncoder 获取日志格式配置
func getConfigEncoder() zapcore.EncoderConfig {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.TimeKey = timeKey
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	return encoderConfig
}

// InitZapLog 初始化日志的配置项
func InitZapLog() {
	var core zapcore.Core
	logLevel := zapcore.Level(settings.Settings.ZapLogConfig.LogLevel)
	fileInputCore := zapcore.NewCore(
		zapcore.NewJSONEncoder(getConfigEncoder()), // json 格式
		getWriteSyncer(),                           // 向文件输出日志
		logLevel)
	stdoutOutCore := zapcore.NewCore(
		zapcore.NewConsoleEncoder(getConfigEncoder()), // 简单输出格式
		zapcore.Lock(os.Stdout),                       // 向控制台输出
		logLevel)
	switch settings.Settings.Mode {
	case "dev": // 开发模式
		core = zapcore.NewTee(fileInputCore, stdoutOutCore)
	case "release": // 生产模式
		core = fileInputCore
	default:
		log.Fatalln("only dev or release mode was allowed")
	}
	logger = zap.New(core, zap.AddCaller())
	showCallerLogger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)) // 显示函数调用者所在的行数
	sugarLogger = logger.Sugar()
}

func Sync() {
	_ = logger.Sync()
	_ = sugarLogger.Sync()
	_ = showCallerLogger.Sync()
}

func L() *zap.Logger {
	return logger
}

func S() *zap.SugaredLogger {
	return sugarLogger
}

func CallerL() *zap.Logger {
	return showCallerLogger
}
